home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / misc / kc / original / kc.c < prev    next >
C/C++ Source or Header  |  1999-06-14  |  31KB  |  1,721 lines

  1. /*
  2.  *    kc.c : kanji code convert ( Version 1.8 ).
  3.  *    Copyright(C) 1989-95 MUKAWA,Susumu mukawa@ctec.tn-sec.ntt.jp
  4.  *    Permit anyone to use, modify, redistribute this software.
  5.  */
  6.  
  7. #include    <stdio.h>
  8. #include    "ctypes.h"
  9.  
  10. #define    ESC        '\033'
  11. #define    SO        '\016'
  12. #define    SI        '\017'
  13.  
  14. #define    JIS2_KANJI    "\033$@"
  15. #define    JIS2_ASCII    "\033(J"
  16. #define    JIS2_KANA    "\033(I"
  17. #define    JIS3_KANJI    "\033$B"
  18. #define    JIS3_ASCII    "\033(J"
  19. #define    JIS4_KANJI    "\033$B"
  20. #define    JIS4_ASCII    "\033(B"
  21. #define    JIS4_KANA    "\033(I"
  22. #define    CT_KANJI    "\033$(B"
  23. #define    CT_ASCII    "\033(B"
  24. #define    CT_KANA        "\033)I"
  25. #define    CT_LATIN1    "\033-A"
  26.  
  27. #define    ILLEGAL        (-2)
  28. #define    UNKNOWN        (-1)
  29. #define    JIS        (0)
  30. #define    JIS2        (2)
  31. #define    JIS3        (3)
  32. #define    JIS4        (4)
  33. #define    SJIS        (5)
  34. #define    EUC        (6)
  35. #define    CT        (7)
  36. #define    VAGUENESS    (100)
  37.  
  38. #define    ASCII_MODE    (0)
  39. #define    KANJI_MODE    (1)
  40. #define    KANA_MODE    (2)
  41.  
  42. #define    CHECK_SIZE    (1024)        /* code check default size    */
  43.  
  44. int    bufSize = CHECK_SIZE;
  45.  
  46. int    kanjiInCode  = UNKNOWN;        /* input stream kanji code.    */
  47. int    kanjiOutCode = SJIS;        /* output stream kanji code.
  48.                      * default code is shift jis.    */
  49. int    bit7 = 0;            /* jis is 7 or 8 bit flag.    */
  50. int    kanaInFlag = 0;
  51.  
  52. int    modeFlag = ASCII_MODE;        /* used in jis or ctext conver func */
  53. int    kanaFlag = 0;
  54.  
  55. int    ungetCount = 0;            /* unget buffer current point.    */
  56. int    ungetCount2 = 0;
  57. int    *ungetBuf;            /* my unget buffer.        */
  58.  
  59. void    (*kanjiOutFunc)() = NULL;    /* kanji convert function.    */
  60.  
  61. int    verboseMode = 0;        /* display status ?        */
  62. int    codeCheckOnly = 0;
  63.  
  64. int    getIllegalSeq = 0;
  65.  
  66. /*    print kanji start sequence.
  67.  */
  68. void    JisKanjiSeq()
  69. {
  70.     switch(kanjiOutCode) {
  71.       case JIS2:
  72.         printf(JIS2_KANJI);
  73.         break;
  74.       case JIS3:
  75.         printf(JIS3_KANJI);
  76.         break;
  77.       case JIS4:
  78.         printf(JIS4_KANJI);
  79.         break;
  80.       case CT:
  81.         printf(CT_KANJI);
  82.         break;
  83.     }
  84. }
  85.  
  86. /*    print ascii start sequence.
  87.  */
  88. void    JisAsciiSeq()
  89. {
  90.     switch(kanjiOutCode) {
  91.       case JIS2:
  92.         printf(JIS2_ASCII);
  93.         break;
  94.       case JIS3:
  95.         printf(JIS3_ASCII);
  96.         break;
  97.       case JIS4:
  98.         printf(JIS4_ASCII);
  99.         break;
  100.       case CT:
  101.         printf(CT_ASCII);
  102.         break;
  103.     }
  104. }
  105.  
  106. /*    print kana start sequence.
  107.  */
  108. void    JisKanaSeq()
  109. {
  110.     switch(kanjiOutCode) {
  111.       case JIS2:
  112.         printf(JIS2_KANA);
  113.         break;
  114.       case JIS3:
  115.         break;
  116.       case JIS4:
  117.         printf(JIS4_KANA);
  118.         break;
  119.       case CT:
  120.         printf(CT_KANA);
  121.         break;
  122.     }
  123. }
  124.  
  125. /*    ctext convert to ctext and output.
  126.  */
  127. void        CtoC(c1, c2)
  128. register int    c1, c2;
  129. {
  130.     if(c1) {
  131.         /* ´Á»ú¤Î¾ì¹ç */
  132.         if(modeFlag != KANJI_MODE) {
  133.             JisKanjiSeq();
  134.             modeFlag = KANJI_MODE;
  135.         }
  136.         putchar(c1);
  137.         putchar(c2);
  138.     }
  139.     else if(c2 == 0) {    /* ¸å»ÏËö */
  140.         if(modeFlag == KANJI_MODE)
  141.             JisAsciiSeq();
  142.         if(kanaFlag) {
  143.             printf(CT_LATIN1); /* Latin-1 ¤ò G1 ¤Ë¤â¤É¤¹ */
  144.             kanaFlag = 0;
  145.         }
  146.         modeFlag = ASCII_MODE;
  147.     }
  148.     else if(iskana(c2)) {
  149.         if(!kanaFlag) {
  150.             JisKanaSeq();
  151.             kanaFlag = 1;
  152.         }
  153.         putchar(c2);
  154.     }
  155.     else {
  156.         if(modeFlag != ASCII_MODE) {
  157.             JisAsciiSeq();
  158.             modeFlag = ASCII_MODE;
  159.         }
  160.         if(c2 == '\n' && kanaFlag) {
  161.             printf(CT_LATIN1); /* Latin-1 ¤ò G1 ¤Ë¤â¤É¤¹ */
  162.             kanaFlag = 0;
  163.         }
  164.         putchar(c2);
  165.     }
  166. }
  167.  
  168. /*    ctext convert to jis and output.
  169.  */
  170. void        CtoJ(c1, c2)
  171. register int    c1, c2;
  172. {
  173.     if(c1) {
  174.         /* ´Á»ú¤Î¾ì¹ç */
  175.         if(modeFlag != KANJI_MODE) {
  176.             JisKanjiSeq();
  177.             modeFlag = KANJI_MODE;
  178.         }
  179.         putchar(c1);
  180.         putchar(c2);
  181.     }
  182.     else if(c2 == 0) {    /* ¸å»ÏËö */
  183.         if(modeFlag == KANJI_MODE ||
  184.                 (modeFlag == KANA_MODE && bit7)) {
  185.             JisAsciiSeq();
  186.         }
  187.         modeFlag = ASCII_MODE;
  188.     }
  189.     else if(iskana(c2)) {
  190.         if(modeFlag != KANA_MODE) {
  191.             JisKanaSeq();
  192.             modeFlag = KANA_MODE;
  193.         }
  194.         if(bit7)
  195.             c2 &= 0x7f;
  196.         else
  197.             c2 |= 0x80;
  198.         putchar(c2);
  199.     }
  200.     else {
  201.         if(modeFlag != ASCII_MODE) {
  202.             JisAsciiSeq();
  203.             modeFlag = ASCII_MODE;
  204.         }
  205.         putchar(c2);
  206.     }
  207. }
  208.  
  209. /*    ctext convert to shift jis and output.
  210.  */
  211. void        CtoS(c1, c2)
  212. register int    c1, c2;
  213. {
  214.     if(c1) {
  215.         /* ´Á»ú¤Î¾ì¹ç */
  216.         c1 &= 0xff;
  217.         c2 &= 0xff;
  218.  
  219.         if(c1 & 1)
  220.             c2 += 0x1f;
  221.         else
  222.             c2 += 0x7d;
  223.         if(c2 >= 0x7f)
  224.             ++c2;
  225.         c1 = ((c1 - 0x21) >> 1) + 0x81;
  226.         if(c1 > 0x9f)
  227.             c1 += 0x40;
  228.         putchar(c1);
  229.         putchar(c2);
  230.     }
  231.     else    /* £±¥Ð¥¤¥È·Ïʸ»ú */
  232.         putchar(c2);
  233. }
  234.  
  235. /*    ctext convert to euc and output.
  236.  */
  237. void        CtoE(c1, c2)
  238. register int    c1, c2;
  239. {
  240.     if(c1) {
  241.         /* ´Á»ú¤Î¾ì¹ç */
  242.         putchar(c1 | 0x80);
  243.         putchar(c2 | 0x80);
  244.     }
  245.     else {    /* £±¥Ð¥¤¥È·Ïʸ»ú */
  246.         if(iskana(c2))
  247.             putchar(0x8e);
  248.         putchar(c2);
  249.     }
  250. }
  251.  
  252.  
  253. /*    jis convert to jis and output.
  254.  */
  255. void        JtoJ(c1, c2)
  256. register int    c1, c2;
  257. {
  258.     if(c1) {
  259.         /* ´Á»ú¤Î¾ì¹ç */
  260.         if(modeFlag != KANJI_MODE) {
  261.             JisKanjiSeq();
  262.             modeFlag = KANJI_MODE;
  263.         }
  264.         putchar(c1);
  265.         putchar(c2);
  266.     }
  267.     else if(c2 == 0) {    /* ¸å»ÏËö */
  268.         if(modeFlag == KANJI_MODE ||
  269.                 (modeFlag == KANA_MODE && bit7)) {
  270.             JisAsciiSeq();
  271.         }
  272.         modeFlag = ASCII_MODE;
  273.     }
  274.     else if(kanaInFlag) {
  275.         if(modeFlag != KANA_MODE) {
  276.             JisKanaSeq();
  277.             modeFlag = KANA_MODE;
  278.         }
  279.         if(bit7)
  280.             c2 &= 0x7f;
  281.         else
  282.             c2 |= 0x80;
  283.         putchar(c2);
  284.     }
  285.     else {
  286.         if(modeFlag != ASCII_MODE) {
  287.             JisAsciiSeq();
  288.             modeFlag = ASCII_MODE;
  289.         }
  290.         putchar(c2);
  291.     }
  292. }
  293.  
  294. /*    jis convert to ctext and output.
  295.  */
  296. void        JtoC(c1, c2)
  297. register int    c1, c2;
  298. {
  299.     if(c1) {
  300.         /* ´Á»ú¤Î¾ì¹ç */
  301.         if(modeFlag != KANJI_MODE) {
  302.             JisKanjiSeq();
  303.             modeFlag = KANJI_MODE;
  304.         }
  305.         putchar(c1);
  306.         putchar(c2);
  307.     }
  308.     else if(c2 == 0) {    /* ¸å»ÏËö */
  309.         if(modeFlag == KANJI_MODE)
  310.             JisAsciiSeq();
  311.         if(kanaFlag) {
  312.             printf(CT_LATIN1); /* Latin-1 ¤ò G1 ¤Ë¤â¤É¤¹ */
  313.             kanaFlag = 0;
  314.         }
  315.         modeFlag = ASCII_MODE;
  316.     }
  317.     else if(kanaInFlag) {
  318.         if(!kanaFlag) {
  319.             JisKanaSeq();
  320.             kanaFlag = 1;
  321.         }
  322.         putchar(c2|0x80);
  323.     }
  324.     else {
  325.         if(modeFlag != ASCII_MODE) {
  326.             JisAsciiSeq();
  327.             modeFlag = ASCII_MODE;
  328.         }
  329.         if(c2 == '\n' && kanaFlag) {
  330.             printf(CT_LATIN1); /* Latin-1 ¤ò G1 ¤Ë¤â¤É¤¹ */
  331.             kanaFlag = 0;
  332.         }
  333.         putchar(c2);
  334.     }
  335. }
  336.  
  337.  
  338. /*    jis convert to shift jis and output.
  339.  */
  340. void        JtoS(c1, c2)
  341. register int    c1, c2;
  342. {
  343.     if(c1) {
  344.         /* ´Á»ú¤Î¾ì¹ç */
  345.         c1 &= 0xff;
  346.         c2 &= 0xff;
  347.  
  348.         if(c1 & 1)
  349.             c2 += 0x1f;
  350.         else
  351.             c2 += 0x7d;
  352.         if(c2 >= 0x7f)
  353.             ++c2;
  354.         c1 = ((c1 - 0x21) >> 1) + 0x81;
  355.         if(c1 > 0x9f)
  356.             c1 += 0x40;
  357.         putchar(c1);
  358.         putchar(c2);
  359.     }
  360.     else {    /* £±¥Ð¥¤¥È·Ïʸ»ú */
  361.         if(kanaInFlag)
  362.             c2 |= 0x80;
  363.         putchar(c2);
  364.     }
  365. }
  366.  
  367. /*    jis convert to euc and output.
  368.  */
  369. void        JtoE(c1, c2)
  370. register int    c1, c2;
  371. {
  372.     if(c1) {
  373.         /* ´Á»ú¤Î¾ì¹ç */
  374.         putchar(c1 | 0x80);
  375.         putchar(c2 | 0x80);
  376.     }
  377.     else {    /* £±¥Ð¥¤¥È·Ïʸ»ú */
  378.         if(kanaInFlag) {
  379.             putchar(0x8e);
  380.             c2 |= 0x80;
  381.         }
  382.         else if(iskana(c2))
  383.             putchar(0x8e);
  384.         putchar(c2);
  385.     }
  386. }
  387.  
  388. /*    shift jis convert to jis and output.
  389.  */
  390. void        StoJ(c1, c2)
  391. register int    c1, c2;
  392. {
  393.     if(c1) {
  394.         /* ´Á»ú¤Î¾ì¹ç */
  395.         if(modeFlag != KANJI_MODE) {
  396.             JisKanjiSeq();
  397.             modeFlag = KANJI_MODE;
  398.         }
  399.  
  400.         c1 &= 0xff;        /* Shift-JIS first byte */
  401.         c2 &= 0xff;        /* Shift-JIS second byte */
  402.  
  403.         c1 -= (c1 < 0xa0) ? 0x71 : 0xb1;
  404.         c1 = (c1 << 1) + 1;
  405.         if(c2 > 0x7f)
  406.             --c2;
  407.         if(c2 > 0x9d) {
  408.             c2 -= 0x7d;
  409.             ++c1;
  410.         }
  411.         else
  412.             c2 -= 0x1f;
  413.         putchar(c1);
  414.         putchar(c2);
  415.     }
  416.     else {    /* £±¥Ð¥¤¥È·Ïʸ»ú */
  417.         if(iskana(c2)) {
  418.             if(modeFlag != KANA_MODE) {
  419.                 JisKanaSeq();
  420.                 modeFlag = KANA_MODE;
  421.             }
  422.             if(bit7)
  423.                 c2 &= 0x7f;
  424.         }
  425.         else {
  426.             if(modeFlag != ASCII_MODE) {
  427.                 JisAsciiSeq();
  428.                 modeFlag = ASCII_MODE;
  429.             }
  430.         }
  431.         if(c2)    putchar(c2);
  432.     }
  433. }
  434.  
  435. /*    shift jis convert to ctext and output.
  436.  */
  437. void        StoC(c1, c2)
  438. register int    c1, c2;
  439. {
  440.     if(c1) {
  441.         /* ´Á»ú¤Î¾ì¹ç */
  442.         if(modeFlag != KANJI_MODE) {
  443.             JisKanjiSeq();
  444.             modeFlag = KANJI_MODE;
  445.         }
  446.  
  447.         c1 &= 0xff;        /* Shift-JIS first byte */
  448.         c2 &= 0xff;        /* Shift-JIS second byte */
  449.  
  450.         c1 -= (c1 < 0xa0) ? 0x71 : 0xb1;
  451.         c1 = (c1 << 1) + 1;
  452.         if(c2 > 0x7f)
  453.             --c2;
  454.         if(c2 > 0x9d) {
  455.             c2 -= 0x7d;
  456.             ++c1;
  457.         }
  458.         else
  459.             c2 -= 0x1f;
  460.         putchar(c1);
  461.         putchar(c2);
  462.     }
  463.     else if(c2 == 0) {    /* ¸å»ÏËö */
  464.         if(modeFlag == KANJI_MODE)
  465.             JisAsciiSeq();
  466.         if(kanaFlag) {
  467.             printf(CT_LATIN1); /* Latin-1 ¤ò G1 ¤Ë¤â¤É¤¹ */
  468.             kanaFlag = 0;
  469.         }
  470.         modeFlag = ASCII_MODE;
  471.     }
  472.     else if(iskana(c2)) {
  473.         if(!kanaFlag) {
  474.             JisKanaSeq();
  475.             kanaFlag = 1;
  476.         }
  477.         putchar(c2);
  478.     }
  479.     else {    /* ASCII character */
  480.         if(modeFlag == KANJI_MODE) {
  481.             JisAsciiSeq();
  482.             modeFlag = ASCII_MODE;
  483.         }
  484.         if(c2 == '\n' && kanaFlag) {
  485.             printf(CT_LATIN1); /* Latin-1 ¤ò G1 ¤Ë¤â¤É¤¹ */
  486.             kanaFlag = 0;
  487.         }
  488.         putchar(c2);
  489.     }
  490. }
  491.  
  492.  
  493. /*    shift jis convert to shift jis and output.
  494.  */
  495. void        StoS(c1, c2)
  496. register int    c1, c2;
  497. {
  498.     if(c1) {
  499.         /* ´Á»ú¤Î¾ì¹ç */
  500.         putchar(c1);
  501.         putchar(c2);
  502.     }
  503.     else    /* £±¥Ð¥¤¥È·Ïʸ»ú */
  504.         putchar(c2);
  505. }
  506.  
  507. /*    shift jis convert to euc and output.
  508.  */
  509. void        StoE(c1, c2)
  510. register int    c1, c2;
  511. {
  512.     if(c1) {
  513.         /* ´Á»ú¤Î¾ì¹ç */
  514.         c1 &= 0xff;        /* Shift-JIS first byte */
  515.         c2 &= 0xff;        /* Shift-JIS second byte */
  516.         c1 -= (c1 < 0xa0) ? 0x71 : 0xb1;
  517.         c1 = (c1 << 1) + 1;
  518.         if(c2 > 0x7f)
  519.             --c2;
  520.         if(c2 > 0x9d) {
  521.             c2 -= 0x7d;
  522.             ++c1;
  523.         }
  524.         else
  525.             c2 -= 0x1f;
  526.         putchar(c1 | 0x80);
  527.         putchar(c2 | 0x80);
  528.     }
  529.     else {    /* £±¥Ð¥¤¥È·Ïʸ»ú */
  530.         if(iskana(c2))
  531.             putchar(0x8e);
  532.         putchar(c2);
  533.     }
  534. }
  535.  
  536. /*    euc convert to jis and output.
  537.  */
  538. void        EtoJ(c1, c2)
  539. register int    c1, c2;
  540. {
  541.     if(c1 == 0) {    /* ASCII character. */
  542.         if(c2 == 0) {    /* ¸å»ÏËö */
  543.             if(modeFlag == KANJI_MODE ||
  544.                     (modeFlag == KANA_MODE && bit7)) {
  545.                 JisAsciiSeq();
  546.             }
  547.             modeFlag = ASCII_MODE;
  548.         }
  549.         else {
  550.             if(modeFlag != ASCII_MODE) {
  551.                 JisAsciiSeq();
  552.                 modeFlag = ASCII_MODE;
  553.             }
  554.             putchar(c2);
  555.         }
  556.     }
  557.     else if(isEkana1(c1)) {
  558.         if(bit7) {
  559.             if(modeFlag != KANA_MODE) {
  560.                 JisKanaSeq();
  561.                 modeFlag = KANA_MODE;
  562.             }
  563.             c2 &= 0x7f;
  564.         }
  565.         else {
  566.             if(modeFlag != ASCII_MODE) {
  567.                 JisAsciiSeq();
  568.                 modeFlag = ASCII_MODE;
  569.             }
  570.         }
  571.         putchar(c2);
  572.     }
  573.     else {
  574.         /* ´Á»ú¤Î¾ì¹ç */
  575.         if(modeFlag != KANJI_MODE) {
  576.             JisKanjiSeq();
  577.             modeFlag = KANJI_MODE;
  578.         }
  579.         putchar(c1 & 0x7f);
  580.         putchar(c2 & 0x7f);
  581.     }
  582. }
  583.  
  584. /*    euc convert to ctext and output.
  585.  */
  586. void        EtoC(c1, c2)
  587. register int    c1, c2;
  588. {
  589.     if(c1 == 0) {    /* ASCII character. */
  590.         if(c2 == 0) {    /* ¸å»ÏËö */
  591.             if(modeFlag == KANJI_MODE)
  592.                 JisAsciiSeq();
  593.             if(kanaFlag) {
  594.                 printf(CT_LATIN1); /* Latin-1 ¤ò G1 ¤Ë¤â¤É¤¹ */
  595.                 kanaFlag = 0;
  596.             }
  597.             modeFlag = ASCII_MODE;
  598.         }
  599.         else {
  600.             if(modeFlag != ASCII_MODE) {
  601.                 JisAsciiSeq();
  602.                 modeFlag = ASCII_MODE;
  603.             }
  604.             if(c2 == '\n' && kanaFlag) {
  605.                 printf(CT_LATIN1); /* Latin-1 ¤ò G1 ¤Ë¤â¤É¤¹ */
  606.                 kanaFlag = 0;
  607.             }
  608.             putchar(c2);
  609.         } }
  610.     else if(isEkana1(c1)) {
  611.         if(!kanaFlag) {
  612.             JisKanaSeq();
  613.             kanaFlag = 1;
  614.         }
  615.         putchar(c2);
  616.     }
  617.     else {    /* ´Á»ú¤Î¾ì¹ç */
  618.         if(modeFlag != KANJI_MODE) {
  619.             JisKanjiSeq();
  620.             modeFlag = KANJI_MODE;
  621.         }
  622.         putchar(c1 & 0x7f);
  623.         putchar(c2 & 0x7f);
  624.     }
  625. }
  626.  
  627. /*    euc convert to shift jis and output.
  628.  */
  629. void        EtoS(c1, c2)
  630. register int    c1, c2;
  631. {
  632.     if(c1 == 0)    /* £±¥Ð¥¤¥È·Ïʸ»ú */
  633.         putchar(c2);
  634.     else if(isEkana1(c1))
  635.         putchar(c2);
  636.     else {    /* ´Á»ú¤Î¾ì¹ç */
  637.         c1 &= 0x7f;
  638.         c2 &= 0x7f;
  639.         if(c1 & 1)
  640.             c2 += 0x1f;
  641.         else
  642.             c2 += 0x7d;
  643.         if(c2 >= 0x7f)
  644.             ++c2;
  645.         c1 = ((c1 - 0x21) >> 1) + 0x81;
  646.         if(c1 > 0x9f)
  647.             c1 += 0x40;
  648.         putchar(c1);
  649.         putchar(c2);
  650.     }
  651. }
  652.  
  653. /*    euc convert to euc and output.
  654.  */
  655. void        EtoE(c1, c2)
  656. register int    c1, c2;
  657. {
  658.     if(c1) {
  659.         /* ´Á»ú¤Î¾ì¹ç */
  660.         putchar(c1);
  661.         putchar(c2);
  662.     }
  663.     else    /* £±¥Ð¥¤¥È·Ïʸ»ú */
  664.         putchar(c2);
  665. }
  666.  
  667. void        NoConv(c1, c2)
  668. register int    c1, c2;
  669. {
  670.     if(c1)    putchar(c1);
  671.     if(c2)    putchar(c2);
  672. }
  673.  
  674. /*    get character from the stream with my unget buffer.
  675.  */
  676. fGetc(fp)
  677. FILE    *fp;
  678. {
  679.     int    fgetc();
  680.  
  681.     if(ungetCount2) {
  682.         if(ungetCount < ungetCount2)
  683.             return(ungetBuf[ungetCount++]);
  684.         else {
  685.             ungetCount = ungetCount2 = 0;
  686.             return(fgetc(fp));
  687.         }
  688.     }
  689.     else if(ungetCount > 0)
  690.         return(ungetBuf[--ungetCount]);
  691.     else
  692.         return(fgetc(fp));
  693. }
  694.  
  695. /*    unget character to my buffer.
  696.  */
  697. void    unGetc(c)
  698. int        c;
  699. {
  700.     if(ungetCount2)
  701.         --ungetCount;
  702.     else if(ungetCount < bufSize)
  703.         ungetBuf[ungetCount++] = c;
  704. }
  705.  
  706. /*    set kanji convert function.
  707.  */
  708. void    SetKanjiOutFunc()
  709. {
  710.     switch(kanjiOutCode) {
  711.       case JIS2:
  712.       case JIS3:
  713.       case JIS4:
  714.         switch(kanjiInCode) {
  715.           case JIS:
  716.             kanjiOutFunc = JtoJ;
  717.             break;
  718.           case CT:
  719.             kanjiOutFunc = CtoJ;
  720.             break;
  721.           case SJIS:
  722.             kanjiOutFunc = StoJ;
  723.             break;
  724.           case EUC:
  725.             kanjiOutFunc = EtoJ;
  726.             break;
  727.         }
  728.         break;
  729.       case CT:
  730.         switch(kanjiInCode) {
  731.           case JIS:
  732.             kanjiOutFunc = JtoC;
  733.             break;
  734.           case CT:
  735.             kanjiOutFunc = CtoC;
  736.             break;
  737.           case SJIS:
  738.             kanjiOutFunc = StoC;
  739.             break;
  740.           case EUC:
  741.             kanjiOutFunc = EtoC;
  742.             break;
  743.         }
  744.         break;
  745.       case SJIS:
  746.         switch(kanjiInCode) {
  747.           case JIS:
  748.           case CT:
  749.             kanjiOutFunc = JtoS;
  750.             break;
  751.           case SJIS:
  752.             kanjiOutFunc = StoS;
  753.             break;
  754.           case EUC:
  755.             kanjiOutFunc = EtoS;
  756.             break;
  757.         }
  758.         break;
  759.       case EUC:
  760.         switch(kanjiInCode) {
  761.           case JIS:
  762.           case CT:
  763.             kanjiOutFunc = JtoE;
  764.             break;
  765.           case SJIS:
  766.             kanjiOutFunc = StoE;
  767.             break;
  768.           case EUC:
  769.             kanjiOutFunc = EtoE;
  770.             break;
  771.         }
  772.         break;
  773.     }
  774. }
  775.  
  776. /*    set ambiguous line number.
  777.  */
  778. void    setFirstErrorLine(errorLine, line)
  779. int    *errorLine;
  780. int    line;
  781. {
  782.     /* If ambiguous line is found at first time,
  783.      *    set that line number.
  784.      */
  785.     if(*errorLine == 0)
  786.         *errorLine = line;
  787. }
  788.  
  789. fGetc2(fp)
  790. FILE    *fp;
  791. {
  792.     int    c;
  793.  
  794.     if(ungetCount) {
  795.         c = ungetBuf[ungetCount2-ungetCount];
  796.         --ungetCount;
  797.         return(c);
  798.     }
  799.         
  800.     c = fgetc(fp);
  801.     if(c == -1)
  802.         return(-1);
  803.  
  804.     ungetBuf[ungetCount2++] = c;
  805.  
  806. #ifdef    DEBUG
  807.     if(c != -1)
  808.         fprintf(stderr, "[%02x]", c);
  809. #endif
  810.     return(c);
  811. }
  812.  
  813. /*    unget character to my buffer.
  814.  */
  815. void    unGetc2(c)
  816. int        c;
  817. {
  818.     if(ungetCount2)
  819.         ++ungetCount;
  820. }
  821.  
  822. CodeCheck(fp)
  823. FILE    *fp;
  824. {
  825.     register int    c, cc, chksize, ccc, cccc;
  826.     int        kCode = UNKNOWN, kCodeMaybe = UNKNOWN;
  827.  
  828.     ungetCount = ungetCount2 = 0;
  829.  
  830.     chksize = bufSize;
  831.     while(chksize > 0 && (c = fGetc2(fp)) != EOF) {
  832.         if(c > 0x7f) {
  833.             if(kCodeMaybe != SJIS && isEkanji(c)) {
  834.                 if((cc = fGetc2(fp)) == EOF) {
  835.                     if(iskana(c)) {
  836.                         /* SJIS ¤« JIS-8bit ¤«¤Î
  837.                          * ¶èÊ̤¬¤Ä¤«¤Ê¤¤¤¦¤Á¤Ë
  838.                          * ¥Õ¥¡¥¤¥ë¤Î½ª¤ê¡£¤·¤ç¤¦¤¬
  839.                          * ¤Ê¤¤¤Î¤Ç SJIS ¤ÈȽÃÇ... */
  840.                         kCode = SJIS;
  841.                         break;
  842.                     }
  843.                     /* ¤Ê¥Ð¥«¤Ê...¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë
  844.                      * ¤È¤·¤«»×¤¨¤Ê¤¤... */
  845.                     break;
  846.                 }
  847.                 else if(isEkanji2(cc)) {
  848.                     if(isSkanji(c) && isSkanji2(cc)) {
  849.                         /* EUC¤«SJIS´Á»ú¤ÎȽÃǤĤ«¤º
  850.                          * ¤È¤ê¤¢¤¨¤º EUC¤ÈȽÃǤ·¤Æ¡¢
  851.                          * ¤µ¤é¤Ëõ¤ë...  */
  852. #ifdef    DEBUG
  853.                         fprintf(stderr, "EUC?\n");
  854. #endif
  855.                         kCodeMaybe = EUC;
  856.                         chksize -= 2;
  857.                         continue;
  858.                     }
  859.                     else if(iskana(c) && iskana(cc)) {
  860.                         /* EUC¤ß¤¿¤¤¤À¤±¤É¡¢
  861.                          * 8bit²¾Ì¾¤¬2¸Ä³¤¤¤¿¤À¤±
  862.                          * ¤«¤âÃΤì¤Ê¤¤¤Î¤Ç¡¢
  863.                          * ¤È¤ê¤¢¤¨¤º EUC¤ÈȽÃǤ·¤Æ¡¢
  864.                          * ¤µ¤é¤Ëõ¤ë...  */
  865. #ifdef    DEBUG
  866.                         fprintf(stderr, "EUC?\n");
  867. #endif
  868.                         kCodeMaybe = EUC;
  869.                         chksize -= 2;
  870.                         continue;
  871.                     }
  872.                     else {
  873.                         /* EUC ·èÄê!! */
  874.                         kCode = EUC;
  875.                         break;
  876.                     }
  877.                 }
  878.                 else if(iskana(c)) {
  879.                     /* 2 ¥Ð¥¤¥ÈÌܤ¬EUC´Á»ú¤¸¤ã¤Ê¤¤
  880.                      * ¤Î¤ÇSJIS²¾Ì¾¤ß¤¿¤¤¤À¤±¤É¡¢
  881.                      * JIS-8bit²¾Ì¾¤«¤âÃΤì¤Ê¤¤¤Î¤Ç¡¢
  882.                      * ¤È¤ê¤¢¤¨¤ºSJIS¤ÈȽÃǤ·¤Æ¡¢
  883.                      * ¤µ¤é¤Ëõ¤ë...  */
  884.                     kCodeMaybe = SJIS;
  885. #ifdef    DEBUG
  886.                     fprintf(stderr, "SJIS?\n");
  887. #endif
  888.                     unGetc2(cc);
  889.                     --chksize;
  890.                     continue;
  891.                 }
  892.             }
  893.             else if(iskana(c)) {
  894.                 /* SJIS¤ß¤¿¤¤¤À¤±¤É¡¢
  895.                  * JIS-8bit²¾Ì¾¤«¤â
  896.                  * ÃΤì¤Ê¤¤¤Î¤Ç¡¢¤µ¤é¤Ëõ¤ë...  */
  897.                 kCodeMaybe = SJIS;
  898. #ifdef    DEBUG
  899.                 fprintf(stderr, "SJIS?\n");
  900. #endif
  901.                 --chksize;
  902.                 continue;
  903.             }
  904.             else if(isEkana1(c)) {
  905.                 if((cc = fGetc2(fp)) == EOF) {
  906.                     /* ¤Ê¥Ð¥«¤Ê...¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë
  907.                      * ¤È¤·¤«»×¤¨¤Ê¤¤... */
  908.                     break;
  909.                 }
  910.                 else if(isEkana2(cc)) {
  911.                     /* EUC ·èÄê!! */
  912.                     kCode = EUC;
  913.                     break;
  914.                 }
  915.                 else {
  916.                     /* ¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë? */
  917.                     unGetc2(cc);
  918.                     --chksize;
  919.                     continue;
  920.                 }
  921.             }
  922.             else if(isSkanji(c)) {
  923.                 if((cc = fGetc2(fp)) == EOF) {
  924.                     /* ¤Ê¥Ð¥«¤Ê...¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë
  925.                      * ¤È¤·¤«»×¤¨¤Ê¤¤... */
  926.                     break;
  927.                 }
  928.                 else if(isSkanji2(cc)) {
  929.                     /* SJIS ·èÄê!! */
  930.                     kCode = SJIS;
  931.                     break;
  932.                 }
  933.                 else {
  934.                     /* ¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë? */
  935.                     unGetc2(cc);
  936.                     --chksize;
  937.                     continue;
  938.                 }
  939.             }
  940.         }
  941.         else if(c == ESC) {
  942.             if((cc = fGetc2(fp)) == EOF) {
  943.                 /* ¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë? */
  944.                 break;
  945.             }
  946.             else if(cc == '$') {
  947.                 if((ccc = fGetc2(fp)) == EOF) {
  948.                     /* ¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë? */
  949.                     unGetc2(cc);
  950.                     --chksize;
  951.                     continue;
  952.                 }
  953.                 else if(ccc == '@' || ccc == 'B') {
  954.                     /* JIS ·èÄê!! */
  955.                     kCode = JIS;
  956.                     break;
  957.                 }
  958.                 else if(ccc == '(') {
  959.                     if((cccc = fGetc2(fp)) == EOF) {
  960.                         /* ¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë? */
  961.                         unGetc2(ccc);
  962.                         unGetc2(cc);
  963.                         --chksize;
  964.                         continue;
  965.                     }
  966.                     else if(cccc == 'B') {
  967.                         /* CTEXT ·èÄê!! */
  968.                         kCode = CT;
  969.                         break;
  970.                     }
  971.                 }
  972.                 else {
  973.                     unGetc2(cc);
  974.                     unGetc2(ccc);
  975.                     --chksize;
  976.                     continue;
  977.                 }
  978.             }
  979.             else if(cc == '(') {
  980.                 if((ccc = fGetc2(fp)) == EOF) {
  981.                     /* ¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë? */
  982.                     unGetc2(cc);
  983.                     --chksize;
  984.                     continue;
  985.                 }
  986.                 else if(ccc == 'H') {
  987.                     /* ESC(H ¤Ï´Ö°ã¤Ã¤¿¥·¡¼¥±¥ó¥¹¤Ç¡¢
  988.                      * ËÜÅö¤Ï¥¹¥§¡¼¥Ç¥óʸ»ú¥»¥Ã¥ÈÍѤǤ¹¡£
  989.                      */
  990.                     kCode = ILLEGAL;
  991.                     break;
  992.                 }
  993.                 else if(ccc == 'J' || ccc == 'B'
  994.                         || ccc == 'I') {
  995.                     /* JIS ·èÄê!! */
  996.                     kCode = JIS;
  997.                     break;
  998.                 }
  999.                 else {
  1000.                     unGetc2(cc);
  1001.                     unGetc2(ccc);
  1002.                     --chksize;
  1003.                     continue;
  1004.                 }
  1005.             }
  1006.             else if(cc == ')') {
  1007.                 if((ccc = fGetc2(fp)) == EOF) {
  1008.                     /* ¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë? */
  1009.                     unGetc2(cc);
  1010.                     --chksize;
  1011.                     continue;
  1012.                 }
  1013.                 else if(ccc == 'I') {
  1014.                     /* CTEXT ·èÄê!! */
  1015.                     kCode = CT;
  1016.                     break;
  1017.                 }
  1018.                 else {
  1019.                     unGetc2(cc);
  1020.                     unGetc2(ccc);
  1021.                     --chksize;
  1022.                     continue;
  1023.                 }
  1024.             }
  1025.             else if(cc == '-') {
  1026.                 if((ccc = fGetc2(fp)) == EOF) {
  1027.                     /* ¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤ë? */
  1028.                     unGetc2(cc);
  1029.                     --chksize;
  1030.                     continue;
  1031.                 }
  1032.                 else if(ccc == 'A') {
  1033.                     /* CTEXT ·èÄê!! */
  1034.                     kCode = CT;
  1035.                     break;
  1036.                 }
  1037.                 else {
  1038.                     unGetc2(cc);
  1039.                     unGetc2(ccc);
  1040.                     --chksize;
  1041.                     continue;
  1042.                 }
  1043.             }
  1044.             else {
  1045.                 unGetc2(cc);
  1046.                 --chksize;
  1047.                 continue;
  1048.             }
  1049.         }
  1050.         else if(c == SO || c == SI) {
  1051.             /* JIS ·èÄê!! */
  1052.             kCode = JIS;
  1053.             break;
  1054.         }
  1055.         else if(codeCheckOnly)
  1056.             --ungetCount2;
  1057.         else {
  1058.             if(kCodeMaybe == UNKNOWN) {
  1059.                 putchar(c);
  1060.                 --ungetCount2;
  1061.             }
  1062.             else
  1063.                 --chksize;
  1064.         }
  1065.     }
  1066.     ungetCount = 0;
  1067.     if(kCode == UNKNOWN)
  1068.         return(kCodeMaybe);
  1069.     else
  1070.         return(kCode);
  1071. }
  1072.  
  1073. /*    stream convert main routine.
  1074.  */
  1075. ConvertMain(fName, fp, errorLine)
  1076. char    *fName;
  1077. FILE    *fp;
  1078. int    *errorLine;
  1079. {
  1080.     register int    c, cc, ccc, cccc;
  1081.     int        failFlag = 1;    /* if there is the character that
  1082.                      * could not convert, this is cleared by zero.*/
  1083.     int        kanjiInFlag = 0;    /* use for JIS. */
  1084.     int        line = 1;        /* current line. */
  1085.  
  1086.     getIllegalSeq = 0;
  1087.     *errorLine = 0;            /* first found ambiguous line. */
  1088.  
  1089.     if(kanjiInCode == UNKNOWN) {
  1090.         kanjiInCode = CodeCheck(fp);
  1091.         if(codeCheckOnly) {
  1092.             if(fName)
  1093.                 printf("%s : ", fName);
  1094.             switch(kanjiInCode) {
  1095.               case -2:    printf("ILLEGAL\n");
  1096.                     getIllegalSeq = 1;  return(0);
  1097.               case -1:    printf("UNKNOWN\n");    break;
  1098.               case  0:    printf("JIS\n");    break;
  1099.               case  5:    printf("SJIS\n");    break;
  1100.               case  6:    printf("EUC\n");    break;
  1101.               case  7:    printf("CT\n");        break;
  1102.             }
  1103.             return(1);
  1104.         }
  1105.         else if(kanjiInCode == ILLEGAL) {
  1106.             getIllegalSeq = 1;
  1107.             return(0);
  1108.         }
  1109. #ifdef    DEBUG
  1110.         else
  1111.             fprintf(stderr, "\n");
  1112. #endif
  1113.         SetKanjiOutFunc();
  1114.     }
  1115.  
  1116.     while((c = fGetc(fp)) != EOF) {
  1117.         if(c > 0x7f) {
  1118.             switch(kanjiInCode) {
  1119.               case EUC:
  1120.                 if(isEkanji(c)) {
  1121.                     /* if euc 1'st byte. */
  1122.                     if((cc = fGetc(fp)) == EOF) {
  1123.                         (*kanjiOutFunc)(0, c);
  1124.                         setFirstErrorLine(errorLine, line);
  1125.                         return(0);
  1126.                     }
  1127.                     else if(isEkanji2(cc)) {
  1128.                         /* if 2'nd byte is euc too !
  1129.                          */
  1130.                         (*kanjiOutFunc)(c, cc);
  1131.                     }
  1132.                     else {
  1133.                         /* if i can't understand 2'nd byte.
  1134.                          */
  1135.                         (*kanjiOutFunc)(0, c);
  1136.                         failFlag = 0;
  1137.                         unGetc(cc);
  1138.                         setFirstErrorLine(errorLine, line);
  1139.                     }
  1140.                 }
  1141.                 else if(isEkana1(c)) {
  1142.                     /* if euc kana 1'st byte. */
  1143.                     if((cc = fGetc(fp)) == EOF) {
  1144.                         (*kanjiOutFunc)(0, c);
  1145.                         setFirstErrorLine(errorLine, line);
  1146.                         return(0);
  1147.                     }
  1148.                     else if(isEkana2(cc))
  1149.                         (*kanjiOutFunc)(c, cc);
  1150.                     else {
  1151.                         /* if i can't understand 2'nd byte.
  1152.                          */
  1153.                         (*kanjiOutFunc)(0, c);
  1154.                         failFlag = 0;
  1155.                         unGetc(cc);
  1156.                         setFirstErrorLine(errorLine, line);
  1157.                     }
  1158.                 }
  1159.                 break;
  1160.               case SJIS:
  1161.                 if(isSkanji(c)) {
  1162.                     /* if shift jis 1'st byte. */
  1163.                     if((cc = fGetc(fp)) == EOF) {
  1164.                         (*kanjiOutFunc)(0, c);
  1165.                         setFirstErrorLine(errorLine, line);
  1166.                         return(0);
  1167.                     }
  1168.                     else if(isSkanji2(cc)) {
  1169.                         /* if 2'nd byte is shift jis too !
  1170.                          */
  1171.                         (*kanjiOutFunc)(c, cc);
  1172.                     }
  1173.                     else {
  1174.                         /* if i can't understand 2'nd byte.
  1175.                          */
  1176.                         (*kanjiOutFunc)(0, c);
  1177.                         failFlag = 0;
  1178.                         unGetc(cc);
  1179.                         setFirstErrorLine(errorLine, line);
  1180.                     }
  1181.                 }
  1182.                 else if(iskana(c))     {
  1183.                     /* if 8 bit kana 1'st byte.*/
  1184.                     (*kanjiOutFunc)(0, c);
  1185.                 }
  1186.                 else {
  1187.                     (*kanjiOutFunc)(0, c);
  1188.                     failFlag = 0;
  1189.                     setFirstErrorLine(errorLine, line);
  1190.                 }
  1191.                 break;
  1192.               case JIS:
  1193.               case CT:
  1194.                 if(iskana(c))     {
  1195.                     /* if 8 bit kana 1'st byte.*/
  1196.                     (*kanjiOutFunc)(0, c);
  1197.                 }
  1198.                 else {
  1199.                     (*kanjiOutFunc)(0, c);
  1200.                     failFlag = 0;
  1201.                     setFirstErrorLine(errorLine, line);
  1202.                 }
  1203.                 break;
  1204.             }
  1205.         }
  1206.         else if(c == ESC) {
  1207.             if((cc = fGetc(fp)) == EOF) {
  1208.                 (*kanjiOutFunc)(0, c);
  1209.                 setFirstErrorLine(errorLine, line);
  1210.                 return(0);
  1211.             }
  1212.             else if(cc == '$') {
  1213.                 if((ccc = fGetc(fp)) == EOF) {
  1214.                     /* if i can't get complete
  1215.                      *    jis sequence.
  1216.                      */
  1217.                     (*kanjiOutFunc)(0, c);
  1218.                     failFlag = 0;
  1219.                     unGetc(cc);
  1220.                     setFirstErrorLine(errorLine, line);
  1221.                 }
  1222.                 else if(ccc == '@' || ccc == 'B') {
  1223.                     /* jis kanji code ! */
  1224.                     kanjiInFlag = 1;
  1225.                     kanaInFlag = 0;
  1226.                 }
  1227.                 else if(ccc == '(') {
  1228.                     if((cccc = fGetc(fp)) == EOF) {
  1229.                         /* if i can't get complete
  1230.                          *    ctext sequence.
  1231.                          */
  1232.                         (*kanjiOutFunc)(0, c);
  1233.                         failFlag = 0;
  1234.                         unGetc(ccc);
  1235.                         unGetc(cc);
  1236.                         setFirstErrorLine(errorLine,
  1237.                                 line);
  1238.                     }
  1239.                     else if(cccc == 'B') {
  1240.                         /* ctext code ! */
  1241.                         kanjiInFlag = 1;
  1242.                         kanaInFlag = 0;
  1243.                     }
  1244.                     else {
  1245.                         (*kanjiOutFunc)(0, ESC);
  1246.                         failFlag = 0;
  1247.                         unGetc(cc);
  1248.                         unGetc(ccc);
  1249.                         unGetc(cccc);
  1250.                         setFirstErrorLine(errorLine,
  1251.                                 line);
  1252.                     }
  1253.                 }
  1254.                 else {
  1255.                     (*kanjiOutFunc)(0, ESC);
  1256.                     failFlag = 0;
  1257.                     unGetc(cc);
  1258.                     unGetc(ccc);
  1259.                     setFirstErrorLine(errorLine, line);
  1260.                 }
  1261.             }
  1262.             else if(cc == '(') {
  1263.                 if((ccc = fGetc(fp)) == EOF) {
  1264.                     /* if i can't get complete
  1265.                      *    jis sequence.
  1266.                      */
  1267.                     (*kanjiOutFunc)(0, c);
  1268.                     failFlag = 0;
  1269.                     unGetc(cc);
  1270.                     setFirstErrorLine(errorLine, line);
  1271.                 }
  1272.                 else if(ccc == 'H') {
  1273.                     /* ESC(H ¤Ï´Ö°ã¤Ã¤¿¥·¡¼¥±¥ó¥¹¤Ç¡¢
  1274.                      * ËÜÅö¤Ï¥¹¥§¡¼¥Ç¥óʸ»ú¥»¥Ã¥ÈÍѤǤ¹¡£
  1275.                      */
  1276.                     failFlag = 0;
  1277.                     getIllegalSeq = 1;
  1278.                     setFirstErrorLine(errorLine, line);
  1279.                     kanaInFlag = kanjiInFlag = 0;
  1280.                 }
  1281.                 else if(ccc == 'J' || ccc == 'B') {
  1282.                     /* jis code ! */
  1283.                     kanaInFlag = kanjiInFlag = 0;
  1284.                 }
  1285.                 else if(ccc == 'I') {
  1286.                     /* jis code ! */
  1287.                     kanjiInFlag = 0;
  1288.                     kanaInFlag = 1;
  1289.                 }
  1290.                 else {
  1291.                     (*kanjiOutFunc)(0, ESC);
  1292.                     failFlag = 0;
  1293.                     unGetc(cc);
  1294.                     unGetc(ccc);
  1295.                     setFirstErrorLine(errorLine, line);
  1296.                 }
  1297.             }
  1298.             else if(cc == ')') {
  1299.                 if((ccc = fGetc(fp)) == EOF) {
  1300.                     /* if i can't get complete
  1301.                      *    ctext sequence.
  1302.                      */
  1303.                     (*kanjiOutFunc)(0, c);
  1304.                     failFlag = 0;
  1305.                     unGetc(cc);
  1306.                     setFirstErrorLine(errorLine, line);
  1307.                 }
  1308.                 else if(ccc == 'I') {
  1309.                     /* ctext code ! */
  1310.                     /* right half of JISX0201 to G1 */
  1311.                 }
  1312.                 else {
  1313.                     (*kanjiOutFunc)(0, ESC);
  1314.                     failFlag = 0;
  1315.                     unGetc(cc);
  1316.                     unGetc(ccc);
  1317.                     setFirstErrorLine(errorLine, line);
  1318.                 }
  1319.             }
  1320.             else if(cc == '-') {
  1321.                 if((ccc = fGetc(fp)) == EOF) {
  1322.                     /* if i can't get complete
  1323.                      *    ctext sequence.
  1324.                      */
  1325.                     (*kanjiOutFunc)(0, c);
  1326.                     failFlag = 0;
  1327.                     unGetc(cc);
  1328.                     setFirstErrorLine(errorLine, line);
  1329.                 }
  1330.                 else if(ccc == 'A') {
  1331.                     /* ctext code ! */
  1332.                     kanjiInFlag = kanaInFlag = 0;
  1333.                 }
  1334.                 else {
  1335.                     (*kanjiOutFunc)(0, ESC);
  1336.                     failFlag = 0;
  1337.                     unGetc(cc);
  1338.                     unGetc(ccc);
  1339.                     setFirstErrorLine(errorLine, line);
  1340.                 }
  1341.             }
  1342.             else {
  1343.                 (*kanjiOutFunc)(0, ESC);
  1344.                 failFlag = 0;
  1345.                 unGetc(cc);
  1346.                 setFirstErrorLine(errorLine, line);
  1347.             }
  1348.         }
  1349.         else if(kanjiInFlag && c > 0x20) {
  1350.             /* if JIS kanji code and kanji mode in.
  1351.              */
  1352.             if((cc = fGetc(fp)) == EOF) {
  1353.                 (*kanjiOutFunc)(0, c);
  1354.                 setFirstErrorLine(errorLine, line);
  1355.                 return(0);
  1356.             }
  1357.             else
  1358.                 (*kanjiOutFunc)(c, cc);
  1359.         }
  1360.         else if(c == SO) {
  1361.             /* jis code ! */
  1362.             kanaInFlag = 1;
  1363.         }
  1364.         else if(c == SI) {
  1365.             /* jis code ! */
  1366.             kanaInFlag = 0;
  1367.         }
  1368.         else {
  1369.             /* ank or controll character.
  1370.              */
  1371.             (*kanjiOutFunc)(0, c);
  1372.             if(c == '\n')
  1373.                 ++line;
  1374.         }
  1375.     }
  1376.  
  1377.     if(kanjiOutCode == JIS2 || kanjiOutCode == JIS3 ||
  1378.             kanjiOutCode == JIS4 ||  kanjiOutCode == CT)
  1379.         /* atoshimatsu */
  1380.         (*kanjiOutFunc)(0, 0);
  1381.     return(failFlag);
  1382. }
  1383.  
  1384. ParseInOptionSub(c)
  1385. char    c;
  1386. {
  1387.     switch(c) {
  1388.       case 'J' :
  1389.       case 'j' :
  1390.       case 'o' :    kanjiInCode = JIS;    break;
  1391.       case 'c' :    kanjiInCode = CT;    break;
  1392.       case 's' :    kanjiInCode = SJIS;    break;
  1393.       case 'e' :    kanjiInCode = EUC;    break;
  1394.       default  :    return(0);
  1395.     }
  1396.     return(1);
  1397. }
  1398.  
  1399. ParseOutOptionSub(c)
  1400. char    c;
  1401. {
  1402.     switch(c) {
  1403.       case 'j' :
  1404.         kanjiOutCode = JIS4;
  1405.         bit7 = 1;
  1406.         switch(kanjiInCode) {
  1407.           case UNKNOWN:
  1408.             kanjiOutFunc = NoConv;
  1409.             break;
  1410.           case JIS:
  1411.             kanjiOutFunc = JtoJ;
  1412.             break;
  1413.           case CT:
  1414.             kanjiOutFunc = CtoJ;
  1415.             break;
  1416.           case SJIS:
  1417.             kanjiOutFunc = StoJ;
  1418.             break;
  1419.           case EUC:
  1420.             kanjiOutFunc = EtoJ;
  1421.             break;
  1422.         }
  1423.         break;
  1424.       case 'J' :
  1425.         kanjiOutCode = JIS3;
  1426.         switch(kanjiInCode) {
  1427.           case UNKNOWN:
  1428.             kanjiOutFunc = NoConv;
  1429.             break;
  1430.           case JIS:
  1431.             kanjiOutFunc = JtoJ;
  1432.             break;
  1433.           case CT:
  1434.             kanjiOutFunc = CtoJ;
  1435.             break;
  1436.           case SJIS:
  1437.             kanjiOutFunc = StoJ;
  1438.             break;
  1439.           case EUC:
  1440.             kanjiOutFunc = EtoJ;
  1441.             break;
  1442.         }
  1443.         break;
  1444.       case 'o' :
  1445.         kanjiOutCode = JIS2;
  1446.         bit7 = 1;
  1447.         switch(kanjiInCode) {
  1448.           case UNKNOWN:
  1449.             kanjiOutFunc = NoConv;
  1450.             break;
  1451.           case JIS:
  1452.             kanjiOutFunc = JtoJ;
  1453.             break;
  1454.           case CT:
  1455.             kanjiOutFunc = CtoJ;
  1456.             break;
  1457.           case SJIS:
  1458.             kanjiOutFunc = StoJ;
  1459.             break;
  1460.           case EUC:
  1461.             kanjiOutFunc = EtoJ;
  1462.             break;
  1463.         }
  1464.         break;
  1465.       case 'c' :
  1466.         kanjiOutCode = CT;
  1467.         switch(kanjiInCode) {
  1468.           case UNKNOWN:
  1469.             kanjiOutFunc = NoConv;
  1470.             break;
  1471.           case JIS:
  1472.             kanjiOutFunc = JtoC;
  1473.             break;
  1474.           case CT:
  1475.             kanjiOutFunc = CtoC;
  1476.             break;
  1477.           case SJIS:
  1478.             kanjiOutFunc = StoC;
  1479.             break;
  1480.           case EUC:
  1481.             kanjiOutFunc = EtoC;
  1482.             break;
  1483.         }
  1484.         break;
  1485.       case 's' :
  1486.         kanjiOutCode = SJIS;
  1487.         switch(kanjiInCode) {
  1488.           case UNKNOWN:
  1489.             kanjiOutFunc = NoConv;
  1490.             break;
  1491.           case JIS:
  1492.             kanjiOutFunc = JtoS;
  1493.             break;
  1494.           case CT:
  1495.             kanjiOutFunc = CtoS;
  1496.             break;
  1497.           case SJIS:
  1498.             kanjiOutFunc = StoS;
  1499.             break;
  1500.           case EUC:
  1501.             kanjiOutFunc = EtoS;
  1502.             break;
  1503.         }
  1504.         break;
  1505.       case 'e' :
  1506.         kanjiOutCode = EUC;
  1507.         switch(kanjiInCode) {
  1508.           case UNKNOWN:
  1509.             kanjiOutFunc = NoConv;
  1510.             break;
  1511.           case JIS:
  1512.             kanjiOutFunc = JtoE;
  1513.             break;
  1514.           case CT:
  1515.             kanjiOutFunc = CtoE;
  1516.             break;
  1517.           case SJIS:
  1518.             kanjiOutFunc = StoE;
  1519.             break;
  1520.           case EUC:
  1521.             kanjiOutFunc = EtoE;
  1522.             break;
  1523.         }
  1524.         break;
  1525.       default  :
  1526.         return(0);
  1527.     }
  1528.     return(1);
  1529. }
  1530.  
  1531. ParseOption(opt)
  1532. char    *opt;
  1533. {
  1534.     if(opt[0] == 'b') {
  1535.         bufSize = atoi(opt+1);
  1536.         if(opt[strlen(opt)-1] == 'k')
  1537.             bufSize *= 1024;
  1538.         return(1);
  1539.     }
  1540.     if(opt[1] == '\0') {
  1541.         if(opt[0] == 'k') {
  1542.             codeCheckOnly = 1;
  1543.             return(1);
  1544.         }
  1545.         else if(opt[0] == 'f') {
  1546.             setbuf(stdout, NULL);
  1547.             return(1);
  1548.         }
  1549.         else if(opt[0] == 'v') {
  1550.             verboseMode = 1;
  1551.             return(1);
  1552.         }
  1553.         else
  1554.             /* if appointed output kanji code only.
  1555.              */
  1556.             return(ParseOutOptionSub(opt[0]));
  1557.     }
  1558.     else if(opt[2] == '\0') {
  1559.         /* if appointed input and output kanji code.
  1560.          */
  1561.         if(!ParseInOptionSub(opt[0]))
  1562.             return(0);
  1563.         return(ParseOutOptionSub(opt[1]));
  1564.     }
  1565.     else
  1566.         return(0);
  1567. }
  1568.  
  1569. #ifdef    MSDOS
  1570. /*    get base file name from path string.
  1571.  */
  1572. char    *GetBaseName(name)
  1573. char    *name;
  1574. {
  1575. #if defined(_MSC_VER) && _MSC_VER >= 800
  1576.     char    *_mbsrchr();
  1577. #else
  1578.     char    *jstrrchr();
  1579. #endif
  1580.     char    *strrchr();
  1581.     char    *p1, *p2;
  1582.  
  1583. #if defined(_MSC_VER) && _MSC_VER >= 800
  1584.     p1 = _mbsrchr(name, '\\');
  1585. #else
  1586.     p1 = jstrrchr(name, '\\');
  1587. #endif
  1588.     p2 = strrchr(name, ':');
  1589.     if(p1 == NULL && p2 == NULL)
  1590.         return(name);
  1591.     else if(p1 != NULL)
  1592.         return(p1+1);
  1593.     else /*if(p2 != NULL)*/
  1594.         return(p2+1);
  1595. }    
  1596. #endif
  1597.  
  1598. void    Usage(prog)
  1599. char    *prog;
  1600. {
  1601. #ifdef    MSDOS
  1602.     /*  remove path name string.
  1603.      */
  1604.     prog = GetBaseName(prog);
  1605. #endif
  1606.     fprintf(stderr, "<< Kanji convert program. (Version 1.8 by s.mukawa) >>\n");
  1607.     fprintf(stderr, "Usage  %s [-k][-bXX][-f][-v][-[input kanjicode][output kanjicode]] [file(s)]\n", prog);
  1608.     fprintf(stderr, "   -k      : code check only(not convert)\n");
  1609.     fprintf(stderr, "   -bXX[k] : code check size(k:kilo-byte,default=1024)\n");
  1610.     fprintf(stderr, "   -f      : non buffering standard output\n");
  1611.     fprintf(stderr, "   -v      : verbose mode\n");
  1612.     fprintf(stderr, "   kanjicode\n");
  1613.     fprintf(stderr, "\t s : shift jis\n");
  1614.     fprintf(stderr, "\t e : euc\n");
  1615.     fprintf(stderr, "\t j : jis { ESC$B [kanji'83], ESC(B [ascii], ESC(I [kana(7bit)] }\n");
  1616.     fprintf(stderr, "\t J : jis { ESC$B [kanji'83], ESC(J [roman] }\n");
  1617.     fprintf(stderr, "\t o : oldjis { ESC$@ [kanji'78], ESC(J [ascii], ESC(I [kana(7bit)] }\n");
  1618.     fprintf(stderr, "\t c : ctext { ESC$(B [kanji'83], ESC(B [ascii], ESC)I [kana(8bit)] }\n");
  1619.     exit(1);
  1620. }
  1621.  
  1622. void    SorryMessage(name, ln)
  1623. char    *name;
  1624. int    ln;
  1625. {
  1626.     if(getIllegalSeq) {
  1627.         fprintf(stderr, "This input stream has ILLEGAL escape sequence [ ESC(H ]!!!!\n");
  1628.         if(kanjiInCode == ILLEGAL)
  1629.             fprintf(stderr, "But, You can convert, if you dare to sepcify input kanji code !!\n");
  1630.     }
  1631.     else if(verboseMode) {
  1632.         fprintf(stderr, "Sorry, i found mysterious character(s).");
  1633.         if(name)
  1634.             fprintf(stderr, "<%s : %d line>\n", name, ln);
  1635.         else
  1636.             fprintf(stderr, "<%d line>\n", ln);
  1637.         fprintf(stderr, "BUT almost completely.\n");
  1638.     }
  1639. }
  1640.  
  1641. main(ac, av)
  1642. int    ac;
  1643. char    *av[];
  1644. {
  1645.     int    i, line, exitStatus = 0;
  1646.     FILE    *fp;
  1647.     char    *env, *getenv();
  1648.  
  1649.     /* get environment value.
  1650.      */
  1651.     env = getenv("KC");
  1652.     if(env != NULL) {
  1653.         char    *tkn, *strtok();
  1654.         tkn = strtok(env, " ");
  1655.         while(tkn != NULL) {
  1656.             if(*tkn == '-')
  1657.                 if(!ParseOption(tkn+1))
  1658.                     Usage(*av);
  1659.             tkn = strtok(NULL, " ");
  1660.         }
  1661.     }
  1662.  
  1663.     /* check option switch.
  1664.      */
  1665.     for(i = 1; i < ac; ++i)
  1666.         if(av[i][0] == '-') {
  1667.             if(!ParseOption(av[i]+1))
  1668.                 Usage(*av);
  1669.         }
  1670.         else
  1671.             break;
  1672.  
  1673.     ungetBuf = (int *)calloc(bufSize, sizeof(int));
  1674.     if(ungetBuf == NULL) {
  1675.         fprintf(stderr, "I can't allocate memory !!\n");
  1676.         exit(1);
  1677.     }
  1678.  
  1679.     /* if put NO option, set default function to JtoS().
  1680.      *     (convertion jis to shift jis convert)
  1681.      */
  1682.     if(kanjiOutFunc == NULL)
  1683.         kanjiOutFunc = JtoS;
  1684.  
  1685.     if(i == ac) {
  1686.         /* read from standard input.
  1687.          */
  1688.         if(!ConvertMain(NULL, stdin, &line)) {
  1689.             SorryMessage(NULL, line);
  1690.             exitStatus |= 1;
  1691.         }
  1692.     }
  1693.     else {
  1694.         int    onlyOneFile = 0;
  1695.         if(i + 1 == ac)
  1696.             onlyOneFile = 1;
  1697.         for(; i < ac; ++i)
  1698.             if((fp = fopen(av[i], "r")) != NULL) {
  1699.                 if(!ConvertMain(onlyOneFile ? NULL : av[i],
  1700.                         fp, &line)) {
  1701.                     SorryMessage(av[i], line);
  1702.                     exitStatus |= 1;
  1703.                 }
  1704.                 (void)fclose(fp);
  1705.                 kanjiInCode  = UNKNOWN;
  1706.             }
  1707.             else {
  1708.                 if(verboseMode)
  1709.                     fprintf(stderr,
  1710.                         "I can't read.(%s)\n", av[i]);
  1711.                 exitStatus |= 1;
  1712.             }
  1713.     }
  1714.     free(ungetBuf);
  1715.     /* process exit status.
  1716.      *    0 := sucess
  1717.      *    1 := fail
  1718.      */
  1719.     exit(exitStatus);
  1720. }
  1721.